#include "stdafx.h"
#include "Graph.h"

namespace GraphTools
{
	Edge::Edge(ptr<Vertex> start, ptr<Vertex> end, int weight)
		:weight(weight),
		flag(false),
		Terminals(list<weak_ptr<Vertex>>())
	{
		Terminals.push_front(weak_ptr<Vertex>(start));
		Terminals.push_back(weak_ptr<Vertex>(end));
		ptr<Edge> the_edge = ptr<Edge>(this);
		start->AddEdge(the_edge);
		end->AddEdge(the_edge);
	}

	const list<weak_ptr<Vertex>> Edge::GetTerminals()
	{
		return this->Terminals;
	}

	bool Edge::operator == (const Edge& e)
	{
		auto front = this->Terminals.front()._Get()->GetName();
		auto end = this->Terminals.back()._Get()->GetName();
		bool res = 
			this->weight == e.weight && 
			this->Terminals.front()._Get() == e.Terminals.front()._Get() &&
			this->Terminals.back()._Get() == e.Terminals.back()._Get();

		return res;
	}

	const weak_ptr<Vertex> Edge::GetOther(const Vertex& v)
	{
		if (*(this->Terminals.front()._Get()) == v)
			return this->Terminals.back();
		else
			return this->Terminals.front();
	}

	const int Edge::GetWeight()
	{
		return this->weight;
	}

	void Edge::ReGen()
	{
		auto start = this->Terminals.front()._Get();
		auto end = this->Terminals.back()._Get();
		ptr<Edge> the_edge = ptr<Edge>(this);
		start->AddEdge(the_edge);
		end->AddEdge(the_edge);
	}

	void Edge::DestroyEdge()
	{
		Vertex* v = this->Terminals.front()._Get();
		v->RemoveEdge(*this);

		v = this->Terminals.back()._Get();
		v->RemoveEdge(*this);
	}

	bool Edge::GetFlag()
	{
		return this->flag;
	}
	void Edge::SetFlag(bool f)
	{
		this->flag = f;
	}
	Vertex* Edge::GetNotVisited()
	{
		Vertex* start = this->Terminals.front()._Get();
		Vertex* end = this->Terminals.back()._Get();

		if (!start->GetFlag() && !end->GetFlag())
		{
			throw "errors\n";
			return NULL;
		}
		if (!end->GetFlag())
		{
			return end;
		}
		if (!start->GetFlag())
		{
			return start;
		}
		return NULL;
	}

}